#include "charger.h"

#include "log.h"
#include "mod_gui.h"
#include "platform.h"
#include "dev.h"
#include "mod_led.h"
#include "data.h"
#include "alarm.h"
#include "errcode.h"
#include "port.h"

#include <string.h>

#define CHAEGE_ITEM_CNT 2

enum STOP_REASON{
    STOP_SERVER = 1, //服务器中止
    STOP_USER,       //用户通过屏幕按键中止
    STOP_RFCARD,     //用户刷卡停机
    STOP_EMTER,      //电表故障停机
    STOP_LOW_CURRT,  //低电流停机
    STOP_START_FAIL,    //启动失败
    STOP_START_TIMEOUT, //启动超时
    STOP_CONTROLLER,    //控制器报上来停止充电
    STOP_CP_NOMAL,      //cp 
    STOP_ALARM,         //告警停机    
};

struct ChargerItem{
    enum ChargeState state; //充电状态
    uint8_t gun_id;
    uint32_t poll_cnt;      //轮询计数
    uint32_t time_cnt;      //分频计数器
    uint32_t charge_begin_time; //开始充电时间
    uint32_t charge_end_time;   //充电结束时间
    uint32_t charge_begin_kwh;  //开始充电电表度数
    uint32_t charge_end_kwh;    //结束充电电表度数
    uint32_t currt_low_cnt;     //低电流计数
    
    uint8_t stop_reason;        //停止充电原因
    uint8_t card_select_id;     //刷卡选择枪号
    uint8_t gun_link;           //枪连接状态
    char_t card_id[17];         //刷卡充电卡号
    uint32_t swip_card_cnt;     //刷卡后的超时计数
    uint8_t stop_finish;        //结束标志
    uint32_t tcost;
};


struct Charger{
    struct ChargerItem item[CHAEGE_ITEM_CNT];
    uint32_t cnt;
    uint8_t net_state;
    uint8_t gunnum;
    uint8_t card_select;
};

#define CHARGE_CMD_INFO_MAX 5
struct ChargeCmdInfo{
    uint8_t flag;     //0 无消息，1 有消息
    enum ChargeCmd cmd;
    uint8_t gun_id;
};

static struct Charger charger;

static struct ChargeCmdInfo charge_cmd_info[CHARGE_CMD_INFO_MAX]={0};

static void charge_set_cmd_info(enum ChargeCmd cmd, uint8_t gun_id){
    for(uint32_t i = 0; i < CHARGE_CMD_INFO_MAX; i++){
        if (charge_cmd_info[i].flag == 0){
            charge_cmd_info[i].cmd = cmd;
            charge_cmd_info[i].gun_id = gun_id;
            charge_cmd_info[i].flag = 1;
            return;
        }
    }

    log(LOG_ERR, "dev_cmd_info buf is full\r\n");
}

static int32_t charge_get_cmd_info(struct ChargeCmdInfo *info){
    for(uint32_t i = 0; i < CHARGE_CMD_INFO_MAX; i++){
        if (charge_cmd_info[i].flag == 1){
            info->cmd = charge_cmd_info[i].cmd;
            info->gun_id = charge_cmd_info[i].gun_id;
            charge_cmd_info[i].flag = 0;
            return 1;
        }
    }
    return 0;
}

static void idle_view_show(struct ChargerItem *item){
    if (item->gun_link){
        gui_show_idle(item->gun_id);		
			  dev_enable_swipcard();
    }else{
        gui_show_wait_gunin(item->gun_id);		  
			  dev_disable_swipcard();		
    }  
}

typedef int32_t (*StateDeal)(struct ChargerItem *item, const void *value);

struct ChargeStateDeal {
    enum ChargeCmd cmd;
    enum ChargeState state;
    StateDeal deal;
};

static int32_t cstate_init_init(struct ChargerItem *item, const void *value){
    dev_init_init(item->gun_id);
    gui_show_init(item->gun_id);
    item->poll_cnt = 0;
    return 0;
}

static int32_t cstate_init_poll(struct ChargerItem *item, const void *value){
    if (dev_is_init_succ(item->gun_id)){
        item->state = CSTATE_IDLE;
    }
    return 0;
}

static int32_t cstate_idle_init(struct ChargerItem *item, const void *value){
    dev_idle_init(item->gun_id);
    led_set_mode(item->gun_id, LED_MODE_NOMAL);
    idle_view_show(item);
    item->card_select_id = 0;
    item->swip_card_cnt = 0;
    memset(item->card_id, 0, sizeof(item->card_id));
    return 0;
}

static int32_t cstate_idle_start(struct ChargerItem *item, const void *value){
    printf("cstate_idle_start m->id = %d\r\n",item->gun_id);
    dev_idle_start(item->gun_id);
    item->poll_cnt = 0;
    item->stop_reason = 0;
  	item->state = CSTATE_WAIT;
    
    return 0;
}

static int32_t cstate_idle_gun_state(struct ChargerItem *item, const void *value){
    idle_view_show(item);
    return 0;
}

static int32_t cstate_idle_card_select(struct ChargerItem *item, const void *value){
    gui_show_card_select(item->card_select_id);
    item->poll_cnt = 5;
    
    return 0;
}

static int32_t cstate_idle_card_swip(struct ChargerItem *item, const void *value){
    //是否要输入密码
    strncpy(item->card_id, (char_t *)value, sizeof(item->card_id));
    if (dev_is_use_net()){
        int32_t ret = dev_card_swip(item->gun_id, (char_t *)value, "e10adc3949ba59abbe56e057f20f883e", 0, 0);
        item->swip_card_cnt = 10*10;     
    }else{
        item->state = CSTATE_WAIT;
    }
    return 0;
}

static int32_t cstate_idle_poll(struct ChargerItem *item, const void *value){  
    if (alarm_is_fault(item->gun_id)){
        item->state = CSTATE_ALARM;
    }
    
    if ((item->time_cnt%10 == 0) && item->poll_cnt){
        item->poll_cnt--;
        if (item->poll_cnt == 0){
            idle_view_show(item);
        }
    }
    
    //show led
    uint8_t net_state = dev_get_net_state();
    uint8_t gun_link = dev_get_gun_link(item->gun_id);
    if (net_state == 0 && dev_is_use_net()){
        led_set_mode(item->gun_id, LED_MODE_NETOFFLINE);           
    }else if (gun_link){
        led_set_mode(item->gun_id, LED_MODE_WAITGUN);
    }else{
        led_set_mode(item->gun_id, LED_MODE_NOMAL);
    }
    if (item->swip_card_cnt){
        item->swip_card_cnt--;
        if (item->swip_card_cnt == 0){
            gui_show_reswip_card(5);
            item->poll_cnt = 5;        
        }
    }
	return 0;
}

static int32_t cstate_wait_init(struct ChargerItem *item, const void *value){
    item->poll_cnt = WAIT_CHARGE_SEC;
    gui_show_wait_charge(item->poll_cnt);
    led_set_mode(item->gun_id, LED_MODE_WAITGUN);
    dev_disable_swipcard();
	  return 0;
}

static int32_t cstate_wait_stop(struct ChargerItem *item, const void *value){
    item->state = CSTATE_CHARGE_END;
    item->stop_reason = STOP_SERVER;
    
	return 0;
}

static int32_t cstate_wait_poll(struct ChargerItem *item, const void *value){

    char_t reasion[5] = {0};
    int32_t ret = dev_is_start_charging_finish(item->gun_id, reasion);
    if (ret == RET_TRUE){
        item->state = CSTATE_CHARGE;
        return 0;
    }else if (ret < 0){
        log(LOG_WARNING, "gun:%d fail reasion:%s\r\n", item->gun_id, reasion);
        gui_show_start_charging_fail(item->gun_id, 10, reasion);
        item->stop_reason = STOP_START_FAIL;
        item->state = CSTATE_CHARGE_END; 
        return 0;
    }else{
        //ret == 0 不处理
    }
    
    if ((item->time_cnt%10 == 0) && item->poll_cnt){
        item->poll_cnt--;
        if (item->poll_cnt == 0){
            log(LOG_WARNING, "gun:%d start over time\r\n", item->gun_id);
            dev_start_charge_fail(item->gun_id, ERR_CODE_DEV_INSIDE_COMM);
            gui_show_start_charging_fail(item->gun_id, 10, ERR_CODE_DEV_INSIDE_COMM);
            item->stop_reason = STOP_START_TIMEOUT;
            item->state = CSTATE_CHARGE_END;
        }
    }
	return 0;
}

static int32_t cstate_charge_init(struct ChargerItem *item, const void *value){  
    item->charge_begin_time = rtc_get_currt_time_sec();
    item->charge_end_time = item->charge_begin_time;
    item->charge_begin_kwh = dev_get_meter_kwh(item->gun_id);
    item->charge_end_kwh = item->charge_begin_kwh;
    item->stop_reason = 0;
    item->currt_low_cnt = 0;
    item->tcost = 0;
    gui_show_charge(item->gun_id);

    led_set_mode(item->gun_id, LED_MODE_CHARGE);

    dev_enable_swipcard();
    
    T_TimeFmt tim={0};
    rtc_get_current_time(&tim);
    data_set_last_charge_time(&tim);
    event_log(item->gun_id, EVENT_START_CHARGE);

	return 0;
}

static int32_t cstate_charge_swip_card(struct ChargerItem *item, const void *value){
    if (strncmp(item->card_id, (char_t *)value, sizeof(item->card_id)) == 0){
        item->stop_reason = STOP_RFCARD;
        item->state = CSTATE_CHARGE_END;        
    }
    return 0;
}

static int32_t cstate_charge_stop(struct ChargerItem *item, const void *value){
  item->state = CSTATE_CHARGE_END;
	return 0;
}

static int32_t cstate_charge_poll(struct ChargerItem *item, const void *value){
    item->charge_end_time = rtc_get_currt_time_sec();
    item->charge_end_kwh = dev_get_meter_kwh(item->gun_id);
    
    if(item->time_cnt % 10 == 0){
        gui_update_charge(item->gun_id, item->charge_end_kwh-item->charge_begin_kwh, item->charge_end_time-item->charge_begin_time);
    }
    
    if (alarm_is_fault(item->gun_id)){
        item->stop_reason = STOP_ALARM;
        item->state = CSTATE_CHARGE_END;
        log(LOG_INFO, "gun:%d stop by alarm\r\n", item->gun_id);
        return 0;
    }

    char_t reasion[5] = {0};
    int32_t ret = dev_is_stop_charge(item->gun_id, reasion);
    if (ret){
        gui_update_charge(item->gun_id, item->charge_end_kwh-item->charge_begin_kwh, item->charge_end_time-item->charge_begin_time);
        item->stop_reason = STOP_CP_NOMAL;
        item->state = CSTATE_CHARGE_END;
        return 0; 
    }

    if (item->time_cnt%10 == 0){
        if (dev_is_low_current(item->gun_id)){
            item->currt_low_cnt++;
            
            if (item->currt_low_cnt > 60*3){
                item->stop_reason = STOP_LOW_CURRT;
                item->state = CSTATE_CHARGE_END;
                log(LOG_INFO, "ac gun:%d stop by low currt alarm\r\n", item->gun_id);
            }
        }else{
            item->currt_low_cnt = 0;
        }
    }
 
	return 0;
}

static int32_t cstate_charge_end_init(struct ChargerItem *item, const void *value){
    if (item->stop_reason == STOP_SERVER 
        || item->stop_reason == STOP_USER 
        || item->stop_reason == STOP_EMTER 
        || item->stop_reason == STOP_LOW_CURRT 
        || item->stop_reason == STOP_RFCARD
        || item->stop_reason == STOP_CP_NOMAL
        || item->stop_reason == STOP_ALARM){

        dev_stop_charge(item->gun_id, NULL);
    }
    item->stop_finish = 0;    
    item->poll_cnt = 10;
    dev_disable_swipcard();
    event_log(item->gun_id, EVENT_END_CHARGE);
    return 0;
}

static int32_t cstate_charge_end_gui_return(struct ChargerItem *item, const void *value){
    item->state = CSTATE_IDLE;
    
    return 0;
}

static int32_t cstate_charge_end_poll(struct ChargerItem *item, const void *value){
 
    if (alarm_is_fault(item->gun_id)){
        led_set_mode(item->gun_id, LED_MODE_ALARM);
    }else{
        led_set_mode(item->gun_id, LED_MODE_NOMAL);
    }    
   
    if (item->stop_finish == 0){
        int32_t ret = dev_is_stop_charge_finish(item->gun_id);
        if (ret == RET_TRUE){
            item->stop_finish = 3;
            item->poll_cnt = 1;
            
            switch(item->stop_reason){
            case STOP_SERVER:
                gui_show_charge_end(item->gun_id, item->charge_end_kwh-item->charge_begin_kwh, item->charge_end_time-item->charge_begin_time, "APP停止");
            break;
            case STOP_USER:
                gui_show_charge_end(item->gun_id, item->charge_end_kwh-item->charge_begin_kwh, item->charge_end_time-item->charge_begin_time, "屏幕停止");
                dev_stop_charge_up_client(item->gun_id, ERR_CODE_STOP_SCREEN);
            break;
            case STOP_RFCARD:
                printf("stop rfcard\r\n");
                gui_show_charge_end(item->gun_id, item->charge_end_kwh-item->charge_begin_kwh, item->charge_end_time-item->charge_begin_time, "刷卡停止");
                dev_stop_charge_up_client(item->gun_id, ERR_CODE_STOP_RFCARD);  
            break;
            case STOP_LOW_CURRT:
                gui_show_charge_end(item->gun_id, item->charge_end_kwh-item->charge_begin_kwh, item->charge_end_time-item->charge_begin_time, "低电流停止");
                dev_stop_charge_up_client(item->gun_id, ERR_CODE_STOP_LOW_CURRT);          
            break;
            case STOP_CP_NOMAL:
                
                gui_show_charge_end(item->gun_id, item->charge_end_kwh-item->charge_begin_kwh, item->charge_end_time-item->charge_begin_time, "正常停止");
                dev_stop_charge_up_client(item->gun_id, ERR_CODE_STOP_NOMAL);                
            break;
            case STOP_ALARM:
            {
                char_t alarm[5]={0};
                alarm_get_alarmcode(item->gun_id, alarm);
                char_t alarm_desc[40]={0};
                alarm_get_alarm_desc(item->gun_id, alarm_desc);
                gui_show_charge_end(item->gun_id, item->charge_end_kwh-item->charge_begin_kwh, item->charge_end_time-item->charge_begin_time, alarm_desc);
                dev_stop_charge_up_client(item->gun_id, alarm);    
                printf("alarm stop:%s\r\n", alarm_desc);
            }
            break;

            case STOP_START_FAIL:

            break;
            case STOP_START_TIMEOUT:

            break;
            case STOP_CONTROLLER:

            break;
            default:
            
            break;
            }        
        }
    }
    
    if ((item->time_cnt%10 == 0) && item->poll_cnt){
        item->poll_cnt--;
    }

    if (item->poll_cnt == 0 && (dev_get_dev_mode() == DEV_CHARGE_MODE_AC || (dev_get_gun_link(item->gun_id) == 0))){
        item->stop_finish = 0;
        if (alarm_is_fault(item->gun_id)){
            item->state = CSTATE_ALARM;
        }else if (item->stop_reason == STOP_START_FAIL || item->stop_reason == STOP_START_TIMEOUT){
            item->state = CSTATE_IDLE;
        }else {
            item->state = CSTATE_SETTLE;
        }
    }
    return 0;
}

static int32_t cstate_settle_init(struct ChargerItem *item, const void *value){
    item->poll_cnt = 5;
    int32_t total_kwh = item->charge_end_kwh - item->charge_begin_kwh;
    int32_t total_sec = item->charge_end_time - item->charge_begin_time;
    
    gui_show_settle(item->gun_id, total_kwh, total_sec, item->tcost, item->poll_cnt);
    
	return 0;
}

static int32_t cstate_settle_poll(struct ChargerItem *item, const void *value){
    if ((item->time_cnt%10 == 0) && item->poll_cnt){
        item->poll_cnt--;
        if (item->poll_cnt == 0){
            if (alarm_is_fault(item->gun_id)){
                item->state = CSTATE_ALARM;
            }else{
                item->state = CSTATE_IDLE;
            }
        }
    }

	return 0;
}

static int32_t cstate_alarm_init(struct ChargerItem *item, const void *value){
    dev_alarm_init(item->gun_id);
    char_t alarm_code[5]={0};
    char_t alarm_desc[50]={0};
    alarm_get_alarmcode(item->gun_id, alarm_code);
    alarm_get_alarm_desc(item->gun_id, alarm_desc);
    gui_show_alarm(item->gun_id, alarm_code, alarm_desc);

    led_set_mode(item->gun_id, LED_MODE_ALARM);
    dev_disable_swipcard();
	return 0;
}

static int32_t cstate_alarm_notify(struct ChargerItem *item, const void *value){
    if (!alarm_is_fault(item->gun_id)){
        item->state = CSTATE_IDLE;
        return 0;
    }
    char_t alarm_code[5]={0};
    char_t alarm_desc[50]={0};
    alarm_get_alarmcode(item->gun_id, alarm_code);
    alarm_get_alarm_desc(item->gun_id, alarm_desc);
    gui_show_alarm(item->gun_id, alarm_code, alarm_desc);
    
    return 0;
}


static int32_t cstate_alarm_poll(struct ChargerItem *item, const void *value){
    if (!alarm_is_fault(item->gun_id)){
        item->state = CSTATE_IDLE;
    }  

	return 0;
}


static const struct ChargeStateDeal g_charge_state[] = {
    {CCMD_INIT,         CSTATE_INIT, cstate_init_init},
    {CCMD_POLL,         CSTATE_INIT, cstate_init_poll},

    {CCMD_INIT, 		    CSTATE_IDLE, cstate_idle_init},
	  {CCMD_START,        CSTATE_IDLE, cstate_idle_start},
    {CCMD_GUN_STATE,    CSTATE_IDLE, cstate_idle_gun_state},
    {CCMD_CARD_SELECT,  CSTATE_IDLE, cstate_idle_card_select},
    {CCMD_CARD_SWIP,    CSTATE_IDLE, cstate_idle_card_swip},
	  {CCMD_POLL,         CSTATE_IDLE, cstate_idle_poll},
	
	  {CCMD_INIT,         CSTATE_WAIT, cstate_wait_init},
	  {CCMD_STOP,         CSTATE_WAIT, cstate_wait_stop},
	  {CCMD_POLL,         CSTATE_WAIT, cstate_wait_poll},
	
	  {CCMD_INIT,         CSTATE_CHARGE, cstate_charge_init},
    {CCMD_CARD_SWIP,    CSTATE_CHARGE, cstate_charge_swip_card},
	  {CCMD_STOP,         CSTATE_CHARGE, cstate_charge_stop},
  	{CCMD_POLL,         CSTATE_CHARGE, cstate_charge_poll},

    {CCMD_INIT,         CSTATE_CHARGE_END, cstate_charge_end_init},
    {CCMD_GUI_RETURN,   CSTATE_CHARGE_END, cstate_charge_end_gui_return},
    {CCMD_POLL,         CSTATE_CHARGE_END, cstate_charge_end_poll},
	
	  {CCMD_INIT,         CSTATE_SETTLE, cstate_settle_init},
	  {CCMD_POLL,         CSTATE_SETTLE, cstate_settle_poll},
	
	  {CCMD_INIT,         CSTATE_ALARM, cstate_alarm_init},
    {CCMD_ALARM,        CSTATE_ALARM, cstate_alarm_notify},
	  {CCMD_POLL,         CSTATE_ALARM, cstate_alarm_poll},
};

static int32_t charge_dealcmd(struct ChargerItem *item, enum ChargeCmd cmd, const void *value) {
	int32_t i;
    for(i = 0; i < sizeof(g_charge_state) / sizeof(struct ChargeStateDeal); i++) {
        if (g_charge_state[i].cmd == cmd && g_charge_state[i].state == item->state) {
            return g_charge_state[i].deal(item, value);
        }
    }
    return -1;
}

static char_t *module_state_str[CSTATE_MAX] = {
    /*CSTATE_INIT*/ "init",  //匹配阶段
	/*CSTATE_IDLE*/ "idle",
	/*CSTATE_WAIT*/ "wait",
	/*CSTATE_CHARGE*/ "charge",
	/*CSTATE_CHARGE_END*/ "charge end",
	/*CSTATE_SETTLE*/ "settle",
	/*CSTATE_ALARM*/ "alarm",
};

void charger_print(void){
    printf("****************************************************\r\n");
    printf("cnt:%d\r\n", charger.cnt);
    printf("net_state:%d\r\n", charger.net_state);
    printf("gunnum:%d\r\n", charger.gunnum);
    printf("card_select:%d\r\n", charger.card_select);

    for(uint32_t i=0;i< charger.gunnum;i++) {
        printf("--------------------------------------------\r\n");
        printf("gun:%d state:%d\r\n", charger.item[i].gun_id, charger.item[i].state);
        printf("gun:%d poll_cnt:%d\r\n", charger.item[i].gun_id, charger.item[i].poll_cnt);
        printf("gun:%d time_cnt:%d\r\n", charger.item[i].gun_id, charger.item[i].time_cnt);
        printf("gun:%d charge_begin_time:%u\r\n", charger.item[i].gun_id, charger.item[i].charge_begin_time);
        printf("gun:%d charge_end_time:%u\r\n", charger.item[i].gun_id, charger.item[i].charge_end_time);
        printf("gun:%d charge_begin_kwh:%d\r\n", charger.item[i].gun_id, charger.item[i].charge_begin_kwh);
        printf("gun:%d charge_end_kwh:%d\r\n", charger.item[i].gun_id, charger.item[i].charge_end_kwh);
        printf("gun:%d currt_low_cnt:%d\r\n", charger.item[i].gun_id, charger.item[i].currt_low_cnt);
        printf("gun:%d stop_reason:%d\r\n", charger.item[i].gun_id, charger.item[i].stop_reason);
        printf("gun:%d card_select_id:%d\r\n", charger.item[i].gun_id, charger.item[i].card_select_id);
        printf("gun:%d gun_link:%d\r\n", charger.item[i].gun_id, charger.item[i].gun_link);
        printf("gun:%d card_id:%s\r\n", charger.item[i].gun_id, charger.item[i].card_id);
        printf("gun:%d swip_card_cnt:%d\r\n", charger.item[i].gun_id, charger.item[i].swip_card_cnt);
        printf("gun:%d stop_finish:%d\r\n", charger.item[i].gun_id, charger.item[i].stop_finish);
        printf("gun:%d tcost:%d\r\n", charger.item[i].gun_id, charger.item[i].tcost);       
    }
    printf("****************************************************\r\n");
}


int32_t charge_state_deal(struct ChargerItem *item, enum ChargeCmd cmd, const void *value) {
    enum ChargeState old_state = item->state;
	int32_t ret = charge_dealcmd(item, cmd, value);
    if (old_state != item->state) {
        log(LOG_INFO, "gun[%d] state %s chg to %s\r\n", item->gun_id, module_state_str[old_state], module_state_str[item->state]);
        charge_dealcmd(item, CCMD_INIT, 0);
    }
    return ret;
}

static void charger_sync_gun_state(struct ChargerItem *item){
    uint8_t state = dev_get_gun_link(item->gun_id);
    if (item->gun_link != state){
        item->gun_link = state;
        charge_dealcmd(item, CCMD_GUN_STATE, 0);
    }
}


void item_poll(struct ChargerItem *item){
    //dev_poll();
    charger_sync_gun_state(item);
    charge_state_deal(item, CCMD_POLL, 0);
    item->time_cnt++;
}

int32_t gun_state_all_up(){
    for (int32_t i=0;i<charger.gunnum;i++){
        //dev_update_gun_state(&charger.item[i].mod_info);
    }
    return 0;
}

int32_t charger_start_charge(int32_t gun_id, char_t *reasion){
    if (charger.item[gun_id - 1].state == CSTATE_ALARM){
        alarm_get_alarmcode(gun_id, reasion);
        log(LOG_INFO, "gun[%d] can not start charge code:%s\r\n", gun_id, reasion);
        return -1;
    }
    
    if (charger.item[gun_id - 1].gun_link != 1){
        strncpy(reasion, "100D", 4);
        log(LOG_INFO, "gun[%d] can not start charge gun unlink\r\n", gun_id);
        return -1;
    } 
    if (charger.item[gun_id - 1].state != CSTATE_IDLE){
        strncpy(reasion, "100D", 4);
        log(LOG_INFO, "gun[%d] state not idle\r\n", gun_id);
        return -1;    
    }
    
    charge_set_cmd_info(CCMD_START, gun_id);
    strncpy(reasion, ERR_CODE_SUCC, 4);
    return 0;
}

int32_t charger_sync_time(uint64_t sec){
    
    for (uint32_t i=0;i<charger.gunnum;i++){
        if (charger.item[i].state == CSTATE_CHARGE){
            return -1;
        }
    }
    dev_sync_time(sec);
    gui_sync_time();
    return 0;
}
int32_t charger_sync_timedate(int year, uint8_t mon, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec,uint8_t week){
    
    for (uint32_t i=0;i<charger.gunnum;i++){
        if (charger.item[i].state == CSTATE_CHARGE){
            return -1;
        }
    }
    dev_sync_datetime(year,mon,day,hour,min,sec,week);
    gui_sync_time();
    return 0;
}

int32_t charger_stop_charge_by_server(int32_t gun_id){
    charger.item[gun_id - 1].stop_reason = STOP_SERVER;
    charge_set_cmd_info(CCMD_STOP, gun_id);
    return 0;
}

int32_t charger_stop_charge_by_user(int32_t gun_id){
    charger.item[gun_id - 1].stop_reason = STOP_USER;
    charge_set_cmd_info(CCMD_STOP, gun_id);
    return 0;
}

int32_t charger_settle_set(uint8_t gun_id, uint32_t tcost){
    if (charger.item[gun_id - 1].state == CSTATE_CHARGE_END){
        charger.item[gun_id - 1].tcost = tcost;
    }
    return 0;
}

static void charger_poll(void){
    
    dev_poll();
    
    charger.cnt++;

    //轮询每个模块
    for (int32_t i=0;i<charger.gunnum;i++){
        item_poll(&charger.item[i]);
    }

    //读取刷卡
    char_t cardid[17]={0};
    if (dev_rfcard_read(cardid)){
        charge_state_deal(&charger.item[charger.card_select-1], CCMD_CARD_SWIP, cardid);
    }

    //读取命令
    struct ChargeCmdInfo info={0};
    if (charge_get_cmd_info(&info)){
        charge_state_deal(&charger.item[info.gun_id-1], info.cmd, 0);
    }
    
    //更新网络
    uint8_t net_state = dev_get_net_state();
    if (charger.net_state != net_state){
        charger.net_state = net_state;
        log(LOG_INFO, "update net state:%d\r\n", charger.net_state);

        if (charger.net_state){
            gui_show_net_state_online();
            gun_state_all_up();
            alarm_all_up();
            event_log(0, EVENT_NETON);
        }else{
            gui_show_net_state_offline();
            event_log(0, EVENT_NETOFF);
        }
    }

    //升级
    
    //喂狗
    wdg_feed();  
}


void charger_task(void *para){
    
    while(1){
        charger_poll();
        os_msleep(100);
    }
}

int32_t charger_init(void){
    
    memset(&charger, 0, sizeof(charger));
    charger.gunnum = data_getint("gunnum");
    
    if (charger.gunnum == 1){
        charger.card_select = 1;
    }   
    
    for(int32_t i=0;i<charger.gunnum;i++){
        charger.item[i].gun_id = i+1;
        charger.item[i].state = CSTATE_INIT;
        charge_state_deal(&charger.item[i], CCMD_INIT, NULL);
    }
    
    os_pthread_t charger_thread;
    if (os_pthread_create("charger", &charger_thread, charger_task, NULL,  OS_TASK_PRIO_NOMAL, OS_STACK_SIZE_SUPER_LARGE) != 0){
        return -1;
    }
    return 0;
}

